<script lang="ts" setup>
import { onMounted, ref } from 'vue'
import home from './static/home.svg'
import prev from './static/prev.svg'

interface JumpMap {
  home?: string
  back?: string
}

// title="首页" 设置导航栏中间的标题文字为“首页”
// fixed 是否固定在页面顶部，默认不固定，加了这个就是吸顶
// fontColor="#333" 设置标题和图标的文字颜色为深灰
// backgroundColor="#f5f5f5" 设置导航栏背景颜色
// backgroundImage="" 设置背景图片路径，若为空表示不使用背景图
// :isShowBack="true" 是否显示左侧返回图标
// :isShowLeft="true" 是否显示左侧区域（slot + 返回按钮）
// :isShowRight="true" 是否显示右侧区域（slot）
// :jumpMap="{ back: 'navigateTo', home: 'switchTab' }" 控制返回跳转方式：如果是首页则 switchTab 跳转主页；如果是返回上一页则用 navigateTo
// fixedObstruction 占位元素，防止内容被导航栏遮挡

const props = defineProps({
  title: String,
  homeUrl: { type: String, default: '/pages/index/index' },
  homeIcon: { type: String, default: '' },
  backUrl: { type: String, default: '' },
  backIcon: { type: String, default: '' },
  fixed: { type: Boolean, default: false },
  zIndex: { type: Number, default: 99 },
  backgroundColor: { type: String, default: '#fff' },
  backgroundImage: { type: String, default: '' },
  fontColor: { type: String, default: '#000' },
  isShowBack: { type: Boolean, default: true },
  isShowLeft: { type: Boolean, default: true },
  isShowRight: { type: Boolean, default: true },
  defaultNavBarheight: { type: Number, default: 66 },
  defaultMenuWidth: { type: Number, default: 40 },
  jumpMap: {
    type: Object as () => JumpMap,
    default: () => ({ home: '', back: '' }),
  },
  fixedObstruction: { type: Boolean, default: false },
})

const statusBarHeight = ref(0)
const navBarHeight = ref(props.defaultNavBarheight)
const menuButtonRect = ref({ width: props.defaultMenuWidth })
const height = ref(props.defaultNavBarheight)
const isFirstPage = ref(true)

onMounted(() => {
  init()
})

function init() {
  getRectInfo()
  getPageInfo()
  setTitle()
}

function setTitle() {
  if (typeof document !== 'undefined') {
    document.title = props.title || ''
  }
}

function getRectInfo() {
  const windowInfo = uni.getWindowInfo()
  const deviceInfo = uni.getDeviceInfo()

  statusBarHeight.value = windowInfo.statusBarHeight || 0
  console.log('statusBarHeight', statusBarHeight.value)

  height.value = statusBarHeight.value + props.defaultNavBarheight
  console.log('height', height.value)
  // 平台兼容处理
  try {
    // #ifdef MP-WEIXIN
    if (uni.canIUse('getMenuButtonBoundingClientRect')) {
      const rect = uni.getMenuButtonBoundingClientRect()
      console.log('rect', rect)
      if (rect) {
        menuButtonRect.value = rect
        navBarHeight.value = (rect.top - windowInfo.statusBarHeight) * 2 + rect.height
        height.value = statusBarHeight.value + navBarHeight.value
      }
    }
    // #endif
  }
  catch (error) {
    console.error('获取胶囊按钮位置信息失败', error)
  }
}

function getPageInfo() {
  const pages = getCurrentPages()
  console.log(pages, 'pages1111111')

  isFirstPage.value = pages.length === 1
}

function handleBack() {
  if (!props.isShowBack)
    return
  if (!isFirstPage.value && !props.backUrl) {
    uni.navigateBack({ delta: 1 })
    return
  }
  console.log('handleBack', isFirstPage.value)

  const url = isFirstPage.value ? props.homeUrl : props.backUrl
  console.log(isFirstPage.value, 'isFirstPage.value')
  console.log(props.backUrl, 'props.backUrl')
  console.log(props.homeUrl, 'props.homeUrl')
  console.log(url, 'url')
  console.log(props.jumpMap, 'props.jumpMap')

  const type = isFirstPage.value ? props.jumpMap.home : props.jumpMap.back
  if (!url)
    return
  if (type && typeof uni[type] === 'function') {
    uni[type]({ url })
    return
  }
  try {
    uni.navigateTo({ url })
  }
  catch (err) {
    uni.switchTab({ url })
  }
}

// 导出高度，便于外部使用
defineExpose({
  headerHeight: height,
})
</script>

<template>
  <view>
    <!-- 固定定位的导航栏 -->
    <view
      class="cos-header" :class="{ is_fixed: fixed }" :style="{
        height: `${height}px`,
        backgroundColor,
        zIndex,
        color: fontColor,
      }"
    >
      <image :src="backgroundImage" class="nav-bg" mode="scaleToFill" :style="{ height: `${height}px` }" />
      <div :style="{ height: `${statusBarHeight}px`, backgroundColor: '#f7f7f7' }" />
      <view class="nav-wrapper" :style="{ height: `${navBarHeight}px` }">
        <view
          v-if="isShowLeft" class="nav-back" :style="{ width: `${menuButtonRect.width}px` }"
          @click="handleBack"
        >
          <slot name="left">
            <template v-if="isShowBack">
              <image v-if="isFirstPage" :src="homeIcon || home " class="img" />
              <image v-else :src="backIcon || prev" class="img" />
            </template>
          </slot>
        </view>
        <view class="nav-title">
          <slot>{{ title }}</slot>
        </view>
        <view v-if="isShowRight" class="nav-menu" :style="{ width: `${menuButtonRect.width}px` }">
          <slot name="right" />
        </view>
      </view>
    </view>

    <!-- 占位元素，防止内容被导航栏遮挡 -->
    <view v-if="fixed && fixedObstruction" :style="{ height: `${height}px` }" class="header-placeholder" />
  </view>
</template>

<style scoped>
.cos-header {
  position: relative;
  width: 100vw;
}

.nav-bg {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  width: 100vw;
}

.is_fixed {
  position: fixed;
  top: 0;
  right: 0;
  left: 0;
  z-index: 99;
}

.nav-wrapper {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 8px;
}

.img {
  width: 40rpx;
  height: 40rpx;
}

.nav-back {
  flex-shrink: 0;
}

.nav-title {
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  word-break: break-word;
  text-overflow: ellipsis;
  flex: 1;
}

.nav-menu {
  flex-shrink: 0;
}

.header-placeholder {
  width: 100%;
}
</style>
